﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX;
using Vxl.Utils.Input;
using Vxl.Utils;
using SlimDX.RawInput;
using System.Windows.Forms;

namespace Vxl.Cameras
{
    public class ModelCamera : BaseCamera
    {
        private bool changed = false;
        private float rotationSpeed = 1.0f;
        private float zoomSpeed = 0.001f;

        public ModelCamera(Vector3 position, Vector3 lookat) : base(position, lookat){
        }

        public override void Update(float dt)
        {
            totalYaw = 0.0f;
            totalPitch = 0.0f;
            HandleMouseMovement(dt);
            if (changed)
            {
                Quaternion rotation = Quaternion.RotationAxis(Up, totalYaw) * Quaternion.RotationAxis(Right, totalPitch); //Create a quaternion from the rotations RELATIVE TO YOUR CAMERA AXES.

                Position -= LookAt; //Translate the camera so that the focus is located at the world origin
                Vector4 tmp = Vector3.Transform(Position, rotation); //Rotate the camera around the origin point
                Position = new Vector3(tmp.X, tmp.Y, tmp.Z);
                Position+= LookAt; //Translate back so that the focus is where it should be
                tmp = Vector3.Transform(Up, rotation); //Rotate the Up vector of your camera in the same way as the camera
                Up = new Vector3(tmp.X, tmp.Y, tmp.Z);

                Forward = Vector3.Normalize(LookAt - Position);
                Right = Vector3.Normalize(Vector3.Cross(Up, Forward));

                if (Vector3.Distance(Position, LookAt) < 1.0f)
                {
                    Position = Vector3.Normalize(LookAt - Forward) * 1.001f;
                }

                View = Matrix.LookAtLH(Position, Position + Forward, Up);

                changed = false;
            }
        }

        private void HandleMouseMovement(float dt)
        {
            if (InputManager.input.MouseWheelDelta != 0)
            {
                Vector3 delta = (float)InputManager.input.MouseWheelDelta * zoomSpeed * Forward;
                Position += delta;
                                
                changed = true;
            }
            
            if (InputManager.input.IsButtonDown(MouseButtonFlags.LeftDown) && (InputManager.input.MouseDelta.X != 0 || InputManager.input.MouseDelta.Y != 0))
            {
                changed = true;

                totalYaw += ((float)InputManager.input.MouseDelta.X / aspectRatio) * dt * rotationSpeed;
                totalPitch += ((float)InputManager.input.MouseDelta.Y / aspectRatio) * dt * rotationSpeed;
            
                if (totalYaw < 0.0f)
                    totalYaw += MathDeclarations.TWO_PI;
                else if (totalYaw > MathDeclarations.TWO_PI)
                    totalYaw -= MathDeclarations.TWO_PI;

                if (totalPitch < 0)
                    totalPitch += MathDeclarations.TWO_PI;
                else if (totalPitch > MathDeclarations.TWO_PI)
                    totalPitch -= MathDeclarations.TWO_PI;
            }
        }
    }
}
